package com.css.bjdt_core.validation.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.css.bjdt_core.cell.entity.Cell;
import com.css.bjdt_core.cell.entity.Cell.CellType;
import com.css.bjdt_core.cell.service.CellDataService;
import com.css.bjdt_core.cell.service.CellService;
import com.css.bjdt_core.executive.entity.Exp;
import com.css.bjdt_core.executive.report.ReportCache;
import com.css.bjdt_core.executive.report.ReportRequest;
import com.css.bjdt_core.explain.service.ReportTemplateExplainService;
import com.css.bjdt_core.report.entity.RptTemplateUnitRela;
import com.css.bjdt_core.report.service.ReportTemplateManageService;
import com.css.bjdt_core.report.service.ReportTemplateUnitRelaService;
import com.css.bjdt_core.report.service.ReportTemplateValidationService;
import com.css.bjdt_core.reportPrepare.service.RptDealWithService;
import com.css.bjdt_core.validation.ReportDataValidator;
import com.css.bjdt_core.validation.ValidationExpParser;
import com.css.bjdt_core.validation.util.KeyLocks;

@Service
public class ReportValidateService {
	@Autowired
	private ReportTemplateManageService reportTemplateManageService;
	@Autowired
	private ReportTemplateUnitRelaService reportTemplateUnitRelaService;
	@Autowired
	private ReportTemplateValidationService reportTemplateValidationService;
	@Autowired
	private CellService cellService;
	@Autowired
	private CellDataService cellDataService;
	@Autowired
	private ValidationInfoService validationInfoService;
	@Autowired
	private RptDealWithService rptDealWithService;
	@Autowired
	private ReportExplainValidationService reportExplainValidationService;
	@Autowired
	private ReportTemplateExplainService reportTemplateExplainService;

	private ReportDataValidator validator = ReportDataValidator.getInstance();

	private ReportCache cache = ReportCache.getInstance();

	private static Log logger = LogFactory.getLog(ReportValidateService.class);

	private KeyLocks keyLocks = new KeyLocks();

	/**
	 * 校核报表数据
	 * @param request
	 */
	public void checkReportData(ReportRequest request, boolean isBatch) {
		String annualId = request.getAnnualId();
		String[] templateIds = request.getTemplateIds().toArray(new String[0]);
		/*String lockKey = null;
		if (templateIds.length == 1) {
			lockKey = annualId + request.getReportDzzId() + templateIds[0];
		} else {
			lockKey = annualId + request.getReportDzzId();
		}
		Object lock = keyLocks.getLock(lockKey);
		synchronized (lock) {*/
		long time1 = System.nanoTime();
		init(annualId);
		long time2 = System.nanoTime();
		logger.error("init cost:" + (time2 - time1) / 1000000);
		for (String templateId : templateIds) {
			initValidationRuleByTemplate(templateId);
		}
		long time3 = System.nanoTime();
		logger.error("initValidationRuleByTemplate cost:" + (time3 - time2) / 1000000);
		validateIndicatorData(request, isBatch);
		long time4 = System.nanoTime();
		logger.error("validateIndicatorData cost:" + (time4 - time3) / 1000000);
		//}
	}

	/**
	 * 初始化
	 * @param annualId
	 */
	private void init(String annualId) {
		validator.setCellDataSvc(cellDataService);
		validator.setValidationInfoSvc(validationInfoService);
		validator.setValidationSvc(reportTemplateValidationService);
		validator.setRptDealWithServiceSvc(rptDealWithService);
		validator.setReportExplainValidationServiceSvc(reportExplainValidationService);
		validator.setReportTemplateExplainServiceSvc(reportTemplateExplainService);
		validationInfoService.createTable(annualId);
	}

	/**
	 * 按报表初始化校核规则
	 * @param templateIds
	 */
	private void initValidationRuleByTemplate(String[] templateIds) {
		for (String templateId : templateIds) {
			initValidationRuleByTemplate(templateId);
		}
	}

	/**
	 * 按报表初始化校核规则
	 * @param templateId
	 */
	private void initValidationRuleByTemplate(String templateId) {
		if (cache.get(ReportCache.VALIDATE_CACHE, templateId) != null) {
			return;
		}
		List<Cell> cells = new ArrayList<Cell>();
		List<Cell> inputCells = cellService.getRawCellsByTemplateIdAndType(templateId, CellType.input);
		List<Cell> statCells = cellService.getRawCellsByTemplateIdAndType(templateId, CellType.stat);
		List<Cell> calcCells = cellService.getRawCellsByTemplateIdAndType(templateId, CellType.calc);
		List<Cell> nullCells = cellService.getRawCellsByTemplateIdAndType(templateId, CellType.cellNull);
		cells.addAll(inputCells);
		cells.addAll(statCells);
		cells.addAll(calcCells);
		Map<String, List<Exp>> validationMap = reportTemplateValidationService
				.buildReportValidationMapByTemplate(templateId);
		ValidationExpParser parser = new ValidationExpParser();
		parser.setExpMap(validationMap);
		List<Cell> validationcells = new ArrayList<Cell>();
		for (Cell cell : cells) {
			parser.parseExp(cell);
			if (cell.getValidationExps() != null && cell.getValidationExps().size() > 0) {
				validationcells.add(cell);
			}
		}
		cache.put(ReportCache.VALIDATE_CACHE, templateId, validationcells);
		//存所有CELL的缓存
		List<Cell> cellsValidationGY = new ArrayList<Cell>();
		cellsValidationGY.addAll(inputCells);
		cellsValidationGY.addAll(statCells);
		cellsValidationGY.addAll(calcCells);
		cellsValidationGY.addAll(nullCells);
		cache.put(ReportCache.VALIDATE_CELL_CACHE, templateId, cellsValidationGY);
	}

	/**
	 * 校核指标数据
	 * @param request
	 */
	private void validateIndicatorData(ReportRequest request, boolean isBatch) {
		List<RptTemplateUnitRela> templateUnitRelas = reportTemplateUnitRelaService.getTemplateUnitRela(request);
		validator.validate(templateUnitRelas, isBatch);
	}

	/*private void destory() {
		parser.destory();
		//validator.destory();
	}*/
}
